#ifndef KATANAFILM_H
#define KATANAFILM_H

#include "utils.h"
#include "film/image.h"

#include "parallel.h"

#include <iostream>

#include <FnDisplayDriver/FnKatanaDisplayDriver.h>

class KatanaFilm : public ImageFilm
{
public:
    KatanaFilm(int xres, int yres, Filter *filt, const float crop[4],
               bool openWindow, const std::string outputAddress,
               int frameId, const float frameTime, std::string frameName);

    virtual ~KatanaFilm(void);

    void WriteImage(float splatScale);

    void UpdateDisplay(int x0, int y0, int x1, int y1, float splatScale);

private:
    FnKat::KatanaPipe *pipe;
    FnKat::NewChannelMessage *channel;

    const std::string outputAddress;
    const int frameId;
    const float frameTime;
    std::string frameName;
    bool isConnected;
    int numChannels;

    Mutex *bucketMutex;

    bool openConnection(void);
    void closeConnection(void);
    void sendBucket(int x0, int y0, int x1, int y1, float splatScale);
    bool parseHostname(const char* hostnameString, char* hostName,
                       unsigned long* portNumber);

    static FnKat::NewFrameMessage* getFrameObject(int frameID);
    static void addNewFrameObject(int frameID, FnKat::NewFrameMessage* frame);
    static bool hasObjectForFrame(int frameID);
    static int getNextChannelID(FnKat::NewFrameMessage* frame);

    static std::map<int, FnKat::NewFrameMessage* > _frameMap;
    static std::map<FnKat::NewFrameMessage*, int > _channelMap;
};


KatanaFilm *CreateKatanaFilm(const ParamSet &params, Filter *filter);

#endif // KATANAFILM_H
